package xyz.eden.cloud.common.web.support.infrastructure.gateway;

import lombok.extern.slf4j.Slf4j;
import xyz.eden.cloud.common.core.exception.BusinessException;
import xyz.eden.cloud.common.core.exception.ParameterException;
import xyz.eden.cloud.common.core.json.JsonTool;
import xyz.eden.cloud.common.core.result.ResultSetEnum;
import xyz.eden.cloud.common.core.util.AssertUtils;
import xyz.eden.cloud.common.web.support.domain.ability.model.BaseOperate;
import xyz.eden.cloud.common.web.support.domain.gateway.BaseOperateGateway;
import xyz.eden.cloud.common.web.support.infrastructure.db.po.BasePO;
import xyz.eden.cloud.common.web.support.infrastructure.resource.BaseOperateResource;

/**
 * BaseGatewayImpl
 */
@Slf4j
public abstract class AbstractBaseOperateGateway<Model extends BaseOperate, PO extends BasePO,
        OperateResource extends BaseOperateResource<PO>> implements BaseOperateGateway<Model> {

    @Override
    public Long addInfo(Model model) throws Exception {
        log.info("AbstractBaseOperateGateway.addInfo - modelInfo: [{}].", JsonTool.toJsonStr(model));

        // 1. 参数校验
        Boolean verifyResult = this.verifyAddInfo(model);
        AssertUtils.isTrue(verifyResult, new ParameterException("verify add info fail."));
        // 2. 模型转换
        PO addInfo = this.builderAddInfo(model);
        AssertUtils.notNull(addInfo, new ParameterException("builder add info is null."));
        // 3. 添加信息
        BaseOperateResource<PO> operateResource = this.getOperateResource();
        Long id = operateResource.addInfo(addInfo);
        AssertUtils.notNull(id, new BusinessException(ResultSetEnum.ERROR_BUSINESS.getCode(), "add info fail."));
        return id;
    }

    /**
     * 构建添加信息
     *
     * @param model
     * @return
     */
    abstract PO builderAddInfo(Model model);

    /**
     * 验证添加信息
     *
     * @param model
     * @return
     */
    abstract Boolean verifyAddInfo(Model model);


    @Override
    public Boolean updateInfoById(Model model) throws Exception {
        log.info("AbstractBaseOperateGateway.updateInfoById - modelInfo: [{}].", JsonTool.toJsonStr(model));

        // 1. 参数校验
        Boolean verifyResult = this.verifyUpdateInfo(model);
        AssertUtils.isTrue(verifyResult, new ParameterException("verify update info fail."));
        // 2. 模型转换
        PO updateInfo = this.builderUpdateInfo(model);
        AssertUtils.notNull(updateInfo, new ParameterException("builder update info is null."));
        // 3. 更新信息
        BaseOperateResource<PO> operateResource = this.getOperateResource();
        Boolean updateResult = operateResource.updateInfoById(updateInfo);
        AssertUtils.isTrue(updateResult, new BusinessException(ResultSetEnum.ERROR_BUSINESS.getCode(), "update info fail."));
        return updateResult;
    }

    abstract PO builderUpdateInfo(Model model);

    abstract Boolean verifyUpdateInfo(Model model);

    abstract OperateResource getOperateResource();
}
